package com.yuyou.fn.settlement.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.wens.mq.MessageHandler;
import com.github.wens.mq.RedisMessageQueue;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.github.wens.mybatisplus.toolkit.IdWorker;
import com.yuyou.fn.common.util.*;
import com.yuyou.fn.settlement.constant.Subjects;
import com.yuyou.fn.settlement.entity.ChangeRecord;
import com.yuyou.fn.settlement.service.IChangeRecordService;
import com.yuyou.fn.settlement.service.ISettlementService;
import com.yuyou.fn.settlement.vo.AccountReportQueryVo;
import com.yuyou.fn.settlement.vo.ProfitDetailVo;
import org.springframework.stereotype.Service;

import com.yuyou.fn.settlement.mapper.MainAccountMapper;
import com.yuyou.fn.settlement.entity.MainAccount;
import com.yuyou.fn.settlement.service.IMainAccountService;
import com.github.wens.framework.service.impl.SuperServiceImpl;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *
 * MainAccount 表数据服务层接口实现类
 *
 */
@Service
public class MainAccountServiceImpl extends SuperServiceImpl<MainAccountMapper, MainAccount,Long> implements IMainAccountService {


    @Resource
    private RedisMessageQueue redisMessageQueue ;

    @Resource
    private IChangeRecordService changeRecordService ;

    @Resource
    private ISettlementService settlementService ;




    @PostConstruct
    public void init(){
        MessageHandler messageHandler = new MessageHandler() {
            @Override
            public void onMessage(byte[] bytes) {
                JSONObject jsonObject = JSONS.toJSONObject(bytes);
                String tableName = jsonObject.getString("tableName");
                String event = jsonObject.getString("event");

                if ("delete".equals(event)) {
                    return;
                }

                JSONArray rowList = jsonObject.getJSONArray("rowList");


                for (int i = 0; i < rowList.size(); i++) {
                    MainAccount mainAccount = new MainAccount();
                    mainAccount.setCreateTime(TimeUtils.now());
                    mainAccount.setUpdateTime(TimeUtils.now());
                    JSONObject row = rowList.getJSONObject(i);
                    if (tableName.equals("yyfn.area_team")) {
                        mainAccount.setMainAccountId(row.getLong("area_team_id"));
                        mainAccount.setName(row.getString("name"));
                        mainAccount.setParentMainAccountId(1L);//誉优公司
                        mainAccount.setTag("areaTeam");
                        mainAccount.setAreaTeamId(row.getLong("area_team_id"));
                        mainAccount.setBusTeamId(0L);
                    } else if (tableName.equals("yyfn.bus_team")) {
                        mainAccount.setMainAccountId(row.getLong("bus_team_id"));
                        mainAccount.setName(row.getString("name"));
                        mainAccount.setParentMainAccountId(row.getLong("area_team_id"));//区域
                        mainAccount.setTag("busTeam");
                        mainAccount.setAreaTeamId(row.getLong("area_team_id"));
                        mainAccount.setBusTeamId(row.getLong("bus_team_id"));
                    } else if (tableName.equals("yyfn.teacher")) {
                        mainAccount.setMainAccountId(row.getLong("teacher_id"));
                        mainAccount.setName(row.getString("teacher_name"));
                        mainAccount.setParentMainAccountId(row.getLong("bus_team_id"));//业务组
                        mainAccount.setTag("teacher");
                        mainAccount.setAreaTeamId(row.getLong("area_team_id"));
                        mainAccount.setBusTeamId(row.getLong("bus_team_id"));
                    } else if (tableName.equals("yyfn.student")) {
                        mainAccount.setMainAccountId(row.getLong("student_id"));
                        mainAccount.setName(row.getString("name"));
                        mainAccount.setParentMainAccountId(IdWorker.getId());//无
                        mainAccount.setTag("student");
                        mainAccount.setAreaTeamId(0L);
                        mainAccount.setBusTeamId(0L);
                    }

                    try{
                        MainAccountServiceImpl.this.insertSelective(mainAccount);
                    }catch (Exception e){
                        MainAccountServiceImpl.this.updateSelectiveById(mainAccount);
                    }


                }

            }
        };
        redisMessageQueue.consume("teacher","main:account",messageHandler );
        redisMessageQueue.consume("student","main:account",messageHandler );
        redisMessageQueue.consume("area_team","main:account",messageHandler );
        redisMessageQueue.consume("bus_team","main:account",messageHandler );

    }


    @Override
    public List<MainAccount> findMainAccount(Long areaTeamId, Long busTeamId) {
        Example<MainAccount> example = MainAccount.createExample();
        Example.Criteria criteria = example.createCriteria();
        CriteriaUtils.fillCondition(criteria,areaTeamId , busTeamId );
        example.orderBy("tag");
        List<MainAccount> list = findListByExample(example);
        List<MainAccount> newList = new ArrayList<>(list.size());
        for(MainAccount mainAccount : list ){
            if(0 == mainAccount.getAreaTeamId()  ){
                continue;
            }
            newList.add(mainAccount);
        }
        return newList;
    }

    @Override
    public Page<ChangeRecord> findAccountReportDetailList(AccountReportQueryVo accountReportQueryVo, int pageNo, int pageSize) {
        Example<ChangeRecord> example = ChangeRecord.createExample();
        Example.Criteria criteria = example.createCriteria();
        CriteriaUtils.fillCondition(criteria,accountReportQueryVo );
        criteria.andGreaterThan("amount" , 0 );
        Page<ChangeRecord> page = changeRecordService.findPageByExample(example, pageNo, pageSize);
        return page;
    }

    @Override
    public ProfitDetailVo calProfit(Long mainAccountId, Date startDate, Date endDate) {

        AccountReportQueryVo accountReportQueryVo = new AccountReportQueryVo();
        accountReportQueryVo.setSubject(Subjects.REAL_INCOME);
        accountReportQueryVo.setStartDate(startDate);
        accountReportQueryVo.setEndDate(endDate);
        List<ChangeRecord> realIncomeRecordList = this.findAccountReportDetailList(accountReportQueryVo, 1, 50000).getRecords();
        accountReportQueryVo.setSubject(Subjects.COST);
        List<ChangeRecord> costRecordList = this.findAccountReportDetailList(accountReportQueryVo, 1, 50000).getRecords();


        BigDecimal realIncomeAmount  = new BigDecimal(0) ;
        BigDecimal costAmount  = new BigDecimal(0) ;
        for(ChangeRecord r : realIncomeRecordList ){
            realIncomeAmount = realIncomeAmount.add(r.getAmount());
        }

        for(ChangeRecord r : costRecordList ){
            costAmount = costAmount.add(r.getAmount());
        }

        ProfitDetailVo profitDetailVo = new ProfitDetailVo();
        profitDetailVo.setMainAccountId(mainAccountId);
        profitDetailVo.setRealIncomeAmount(realIncomeAmount);
        profitDetailVo.setCostAmount(costAmount);
        profitDetailVo.setProfitAmount(realIncomeAmount.subtract(costAmount));
        profitDetailVo.setCostRecordList(costRecordList);
        profitDetailVo.setRealIncomeRecordList(realIncomeRecordList);
        profitDetailVo.setStartDate(startDate);
        profitDetailVo.setEndDate(endDate);

        return profitDetailVo;

    }

    @Override
    public BigDecimal sumAmountByQuery(AccountReportQueryVo accountReportQueryVo, boolean isPositive) {
        return autoMapper.sumAmountByQuery(accountReportQueryVo,isPositive);
    }

    @Override
    public BigDecimal sumNotSettleAmount(Long mainAccountId,String subject, Date startDate, Date endDate) {
        return autoMapper.sumNotSettleAmount(mainAccountId,subject,startDate,endDate);
    }

    @Override
    public BigDecimal calBalance(MainAccount mainAccount, BigDecimal amount) {
        return Utils.calProportion(amount,new BigDecimal(7),new BigDecimal(10));
    }

    @Override
    public void settleBalance(MainAccount mainAccount) {
        List<ChangeRecord> incomeRecordList = changeRecordService.findNotSettleChangeRecord(mainAccount.getMainAccountId(), Subjects.REAL_INCOME, null, new Date());
        List<ChangeRecord> costRecordList = changeRecordService.findNotSettleChangeRecord(mainAccount.getMainAccountId(), Subjects.COST, null, new Date());
        BigDecimal income = sum(incomeRecordList);
        BigDecimal cost = sum(costRecordList);
        BigDecimal profit = income.subtract(cost);
        if(profit.compareTo(BigDecimal.ZERO) == 0 ){
            return;
        }

        if(mainAccount.getTag().equals("busTeam")){



            BigDecimal balance = calBalance(mainAccount, profit);

            BigDecimal areaTeamIncome = profit.subtract(balance);

            increaseBalance(mainAccount.getMainAccountId(),balance);

            MainAccount parentMainAccount = findById(mainAccount.getParentMainAccountId());
            Date now = TimeUtils.now();
            ChangeRecord changeRecord = new ChangeRecord();
            changeRecord.setAmount(areaTeamIncome);
            changeRecord.setMainAccountId(parentMainAccount.getMainAccountId());
            changeRecord.setTags("shared:revenue");
            changeRecord.setSubject(Subjects.REAL_INCOME);
            changeRecord.setTrackingId(mainAccount.getMainAccountId());
            changeRecord.setParentMainAccountId(parentMainAccount.getParentMainAccountId());
            changeRecord.setRemark("【"+mainAccount.getName()+"】分成收入");
            changeRecord.setCreateTime(now);
            changeRecord.setUpdateTime(now);
            changeRecord.setSettleStatus(0);
            changeRecord.setDirection(0);
            changeRecordService.insertSelective(changeRecord);
        }else{
            increaseBalance(mainAccount.getMainAccountId(),profit );
        }

        List<Long> idsList = new ArrayList<>(100);
        List<Long> changeRecordIdList = BeanUtils.toList(incomeRecordList, "changeRecordId");
        List<Long> changeRecordIdList2 = BeanUtils.toList(costRecordList, "changeRecordId");
        idsList.addAll(changeRecordIdList);
        idsList.addAll(changeRecordIdList2);
        changeRecordService.updateSettleStatus(idsList, 1 );

    }

    @Override
    public  void increaseBalance(Long mainAccountId, BigDecimal balance) {

        autoMapper.increaseBalance(mainAccountId,balance);
    }

    private BigDecimal sum(List<ChangeRecord> list ) {
        BigDecimal amount  = new BigDecimal(0);
        for(ChangeRecord changeRecord : list ){
            amount = amount.add(changeRecord.getAmount());
        }
        return amount ;
    }


}